﻿using pdfer.FileObjects;
using pdfer.Syntax;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace pdfer.PdfObjecs
{
    internal class ObjStmDictionary : PdfFileObject
    {
        public ObjStmDictionary(PdfFileObject pdfFileObject)
            : base(pdfFileObject)
        {
            if (pdfFileObject.TryGetValue(PdfName.Key_Type, out object? val))
            {
                Type = PdfParserUtils.ParseString(val);
                if (Type != PdfTypeConst.Type_ObjStm)
                {
                    throw new Exception("类型必须是 /ObjStm");
                }
            }
        }
        public String Type { get; set; }

        private Int32? _first;
        /// <summary>
        /// 数据开始偏移量
        /// </summary>
        public Int32 First 
        { 
            get 
            {
                if (_first == null) 
                {
                    if(TryGetValue(PdfName.Key_First, out var _v))
                    {
                        _first = PdfParserUtils.ParseInt32(_v, this);
                    }
                    else
                    {
                        _first = 0;
                    }
                }
                return _first.Value;
            }
        }

        private Int32? _n;
        /// <summary>
        /// 对象个数
        /// </summary>
        public Int32 N 
        {
            get
            {
                if (_n == null)
                {
                    if (TryGetValue(PdfName.Key_N, out var _v))
                    {
                        _n = PdfParserUtils.ParseInt32(_v, this);
                    }
                    else
                    {
                        _n = 0;
                    }
                }
                return _n.Value;
            }
        }

        private KeyValuePair<Int32, Int32>[] kvs;

        public KeyValuePair<Int32, Int32>[] KVs
        {
            get
            {
                if(kvs == null)
                {
                    kvs = new KeyValuePair<Int32, Int32>[N];
                    var _f = First;
                    var idxInfo = base.DecodeStreamData.AsSpan().Slice(0, _f);
                    var idxInfos = Encoding.UTF8.GetString(idxInfo).Split(' ', StringSplitOptions.RemoveEmptyEntries);
                    for (var i = 0; i < idxInfos.Length; i++, i++)
                    {
                        var refId = Int32.Parse(idxInfos[i]);
                        var offset = Int32.Parse(idxInfos[i + 1]) + _f;
                        //
                        kvs[i / 2] = KeyValuePair.Create(refId, offset);
                    }
                }

                return kvs;
            }
        }

        public PdfFileObject GetPdfFileObject(Int32 index) 
        {
            var kv = KVs[index];
            var engine = new PSCompilationEngineV2();
            using var ms = new MemoryStream(DecodeStreamData);
            engine.ParseToPdfFileObject(ms, kv.Value);
            var obj = engine.PdfFileObject;
            obj.No = $"{kv.Key} 0";
            return obj;
        }
    }
}
